<?php

namespace app\index\service;

use app\common\ConfigBase;
use app\common\model\ToolModel;
use app\index\model\WarehousecountryModel;

class WarehousecountryService
{
    static public $typeStr = [
        10 => '采购入库'
        ,20 => '盘盈入库'
    ];
    static public $statusStr = [
        10 => '未确定'
        , 20 => '已确定'
    ];
    static public $advanceStatus = [
        10 => '未释放'
        , 20 => '已释放'
    ];
    static public $advanceType = [
        10 => '调拨'
        , 20 => '盘亏'
        , 30 => '采销'
    ];
    static public $outStatus = [
        10 => '未确定'
        , 20 => '已确定'
    ];
    static public $outType = [
        10 => '调拨出库'
        , 20 => '盘亏出库'
        , 30 => '采销出库'
    ];

    /**
     *生成国家仓入库单 自动类型的不生成明细,手动生成明细
     * @param $param
     * @return array
     * @author xiejunyu
     */
    static public function create($param)
    {
        if (empty($param['bs_code'])) {
            return returnArr(500, '业务单号不存在!');
        }
        $info = ToolModel::findByAttributes('warehouse_country', ['bs_code' => $param['bs_code']]);
        if ($param['type'] == 1) {
            $plan = ToolModel::findByAttributes('ship_plan', ['code' => $param['bs_code']]);
            $param['receipt_warehouse_id'] = $plan['warehouse_id_rec'];
            $param['ship_warehouse_id'] = $plan['warehouse_id_out'];
        }
        if (!empty($info)) {
            return returnArr(500, '已存在国家仓入库单!');
        }
        if (empty($param['list'])) {
            return returnArr(500, '采购明细不能为空!');
        }
        $temp = [];
        $temp['bs_code'] = $param['bs_code'] ?? '';
        $temp['receipt_warehouse_id'] = $param['receipt_warehouse_id'];
        $temp['ship_warehouse_id'] = $param['ship_warehouse_id'] ?? 0;
        //$temp['retail_company'] = $param['purchase_company_id'];
        $temp['type'] = 10;//采购入库
        $temp['status'] = 10;//未确定
        $temp['user'] = $param['user'];
        $temp['ctime'] = $param['ctime'];
        $id = ToolModel::insertData($temp, 'warehouse_country');
        ToolModel::updateData(['id' => $id], ['code' => 'RK' . $id], 'warehouse_country');
        $pd = [];
        if ($param['type'] == 2) {//手动
            foreach ($param['list'] as $v) {
                $tempPd = [];
                $tempPd['warehouse_country_id'] = $id;
                $tempPd['sku'] = $v['sku'];
                $tempPd['sku_name'] = $v['sku_name'];
                $tempPd['quantity'] = $v['quantity'];
                $tempPd['price'] = $v['unit_price'];
                $pd[] = $tempPd;
            }
        }
        !empty($pd) && ToolModel::insertData($pd, 'warehouse_country_detail');
        return returnArr(1, '成功');
    }
    static public function inOutStockByInventoryDo($param){
        if (empty($param['id'])) {
            return returnArr(500, '盘点id不存在!');
        }
        $info = ToolModel::findByAttributes('inventory', ['id' => $param['id']]);
        $list = ToolModel::select('inventory_detail', ['inventory_id' => $param['id']]);
        if(empty($info)||empty($list)){
            return returnArr(500, '盘点不存在!');
        }
        $in=[];
        $out=[];
        foreach ($list as $v){
            if($v['inventory_quantity']>$v['stock_quantity']){
                //盘盈入库
                $in[]=$v;
            }elseif($v['inventory_quantity']<$v['stock_quantity']){
                //出库
                $out[]=$v;
            }
        }
        if (!empty($in)) {
            $ret1=self::inStockByInventory($info,$in);
            if($ret1['code']!=1){
                return returnArr(500,'盘盈入库失败'.$ret1['msg']);
            }
        }
        if (!empty($out)) {
            $ret2=self::outStockByInventory($info,$out);
            if($ret2['code']!=1){
                return returnArr(500,'盘亏出库失败'.$ret2['msg']);
            }
        }
        return returnArr(1);
    }
    /**
     *盘盈入库 或 盘亏出库
     * @param $param
     * @return array
     * @author xiejunyu
     */
    static public function  inOutStockByInventory($param)
    {
        $param['function']='\app\index\service\WarehousecountryService::inOutStockByInventoryDo';
        return ToolModel::dbRollback($param);
    }
    //盘盈入库
    static public function  inStockByInventory($param,$list)
    {
        $info = ToolModel::findByAttributes('warehouse_country', ['bs_code' =>$param['inventory_sn']]);
        if (!empty($info)) {
            return returnArr(500, '已存在国家仓入库单!');
        }
        if (empty($list)) {
            return returnArr(500, '明细不能为空!');
        }
        $temp = [];
        $temp['bs_code'] = $param['inventory_sn'];
        $temp['receipt_warehouse_id'] = $param['warehouse_id'];
        $temp['ship_warehouse_id'] =$param['warehouse_id'];
        $temp['type'] = 20;//盘盈入库
        $temp['status'] = 10;//未确定
        $temp['user'] =CN_NAME;
        $temp['ctime'] = TIME;
        $id = ToolModel::insertData($temp, 'warehouse_country');
        ToolModel::updateData(['id' => $id], ['code' => 'RK' . $id], 'warehouse_country');
        $pd = [];
        foreach ($list as $v) {
            $tempPd = [];
            $tempPd['warehouse_country_id'] = $id;
            $tempPd['sku'] = $v['sku'];
            $tempPd['sku_name'] = $v['sku_name'];
            $tempPd['quantity'] = abs($v['difference_quantity']);
            $tempPd['price'] = $v['unit_price'];
            $pd[] = $tempPd;
        }
        ToolModel::insertData($pd, 'warehouse_country_detail');
        return returnArr(1, '成功');
    }
    //盘亏出库
    static public function outStockByInventory($param,$listTemp)
    {
        $info = ToolModel::findByAttributes('warehouse_country_out', ['bs_code' =>$param['inventory_sn']]);
        if (!empty($info)) {
            return returnArr(500, '已存在国家仓出库单!');
        }
        if (empty($listTemp)) {
            return returnArr(500, '明细不能为空!');
        }
        $temp = [];
        $temp['receipt_warehouse_id'] =0;
        $temp['ship_warehouse_id'] = $param['warehouse_id'];//发货仓库
        $temp['receipt_warehouse_id'] = $param['warehouse_id'];
        $temp['bs_code'] = $param['inventory_sn'];
        $temp['status'] = 10;
        $temp['type'] = 20;
        $temp['user'] = CN_NAME;
        $temp['date'] = TIME;
        $temp['ctime'] = TIME;
        $id = ToolModel::insertData($temp, 'warehouse_country_out');
        $ck = 'CK' . $id;
        ToolModel::updateData(['id' => $id], ['code' => $ck], 'warehouse_country_out');
        $list = [];
        foreach ($listTemp as $v) {
            $temp = [];
            $temp['sku'] = $v['sku'];
            $temp['sku_name'] = $v['sku_name'];
            $temp['quantity'] = abs($v['difference_quantity']);
            $temp['demand_quantity'] = abs($v['difference_quantity']);
            $temp['warehouse_country_out_id'] = $id;
            $temp['price'] = 0;
            $list[] = $temp;
        }
        ToolModel::insertData($list, 'warehouse_country_out_detail');
        return returnArr(1, '', $id);
    }
    //出库确认
    static public function outStockConfirm($param){
        $info = ToolModel::findByAttributes('warehouse_country_out', ['id' =>$param['id']]);
        if($info['status']==20){
            return returnArr(500, '已确定出库!');
        }
        $row = ToolModel::updateData(['id' => $param['id'], 'status' => 10], ['status' => 20, 'date' => TIME], 'warehouse_country_out');
        if (!$row) {
            return returnArr(500, '修改出库状态失败!');
        }
        $listTemp = ToolModel::select('warehouse_country_out_detail', ['warehouse_country_out_id' =>$param['id']]);
        $list=[];
        if(empty($listTemp)){
            return returnArr(500, '明细不能为空!');
        }
        foreach ($listTemp as $v1) {
            $temp1 = $v1;
            $temp1['warehouse_id_out'] = $info['ship_warehouse_id'];
            $temp1['bs_code'] = $info['bs_code'];
            $temp1['code'] = $info['code'];
            //先进先出减库存
            $ret = self::getRecentlyCost($temp1);
            if ($ret['code'] != 1) {
                return $ret;
            }
            $v1['price'] = $ret['data'];
            $list[] = $v1;
        }
        ToolModel::dbInsertOrUpdate('warehouse_country_out_detail',$list);
        // 并减库存 重新库存成本
        foreach ($list as $v) {
            //减可用库存  加预占
            $row = ToolModel::updateData(['sku' => $v['sku'], 'receipt_warehouse_id' => $info['ship_warehouse_id'],'physical_stock'=>['>=',$v['quantity']]],
                [
                    'physical_stock' => ToolModel::raw("physical_stock-{$v['quantity']}")//减实物库存
                    ,'available_stock' => ToolModel::raw("available_stock-{$v['quantity']}")//减可用库存
                ]
                , 'warehouse_country_stock');
            if (!$row) {
                return returnArr(500, '实物库存不足,出库失败');
            }
            $v['receipt_warehouse_id']=$info['ship_warehouse_id'];
            //修改库存成本
            $ret = WarehousecountryModel::getCostSum($v);
            //修改库龄
            WarehousecountryModel::updateSkuStockAge($v);
            if ($ret['code'] != 1) {
                return $ret;
            }
        }
        return returnArr(1, '出库成功',['url'=>'/#/Warehousecountry/out']);
    }

    static public function outStockConfirmDo($param)
    {
        $param['lockFunction']='\app\index\service\WarehousecountryService::outStockConfirm';
        $param['lockTxt']='warehouse_country_lock';
        return ToolModel::lock($param);
    }
    static public function detail($param)
    {
        $result = ToolModel::findByAttributes('warehouse_country', ['id' => $param['id']]);
        $msg = '';
        if (substr($result['bs_code'], 0, 2) == 'FY') {
            //存在发运单号生成明细
            self::createAutoDetail(['code' => $result['bs_code']]);
        }
        $detail = ToolModel::select('warehouse_country_detail', ['warehouse_country_id' => $param['id']]);
        $detail2= self::getDetailHandle($detail,$result['bs_code']);
        $data = self::getListHandle([$result]);
        return returnArr(1, $msg, ['result' => $data[0], 'detail' => $detail2]);
    }
    static public function getDetailHandle($data,$code)
    {
        if(empty($data)){
            return $data;
        }
        $shopAll = ConfigBase::getShopAll();
        if (substr($code, 0, 2) == 'FY') {
            $receive = ToolModel::select('ship_plan_receive', ['code' => $code]);
        }else{
            $receive=[];
        }
        $detail=[];
        foreach ($receive as $v2) {
            $k2=$v2['shop_id'].$v2['sku'];
            $detail[$k2][]=$v2['case_number'];
        }
        foreach ($data as &$v){
            $k2=$v['shop_id'].$v['sku'];
            $v['case_number']=empty($detail[$k2])?'':join(',',$detail[$k2]);
            $v['shop_name']=$shopAll[$v['shop_id']]??'';
        }
        return $data;
    }
    static public function outDetail($param)
    {
        $result = ToolModel::findByAttributes('warehouse_country_out', ['id' => $param['id']]);
        $msg = '';
        $detail = ToolModel::select('warehouse_country_out_detail', ['warehouse_country_out_id' => $param['id']]);
        $data = self::getOutListHandle([$result]);
        return returnArr(1, $msg, ['result' => $data[0], 'detail' => $detail]);
    }

    /**
     *发运单自动生成入库明细
     * @param $param
     * @return array
     * @author xiejunyu
     */
    static public function createAutoDetail($param)
    {
        $planCost = ToolModel::select('ship_plan_cost', ['code' => $param['code']], '*', '', 'sku');
        $receive = ToolModel::select('ship_plan_receive', ['code' => $param['code']]);
        $warehouseCountry = ToolModel::findByAttributes('warehouse_country', ['bs_code' => $param['code']]);
        $planDetail = ToolModel::select('ship_plan_detail', ['ship_plan_id' => substr($param['code'], 2)], 'sku,unit_price,sku_name', '', 'sku');
        $poId= ToolModel::getValue('purchase_order', ['bs_code' => $param['code']], 'id', 'id desc');
        $poDetail = ToolModel::select('purchase_order_detail', ['po_id' =>$poId], 'sku,unit_price,id', '', 'sku');
        //$shipPlanSend = ToolModel::select('ship_plan_send', ['code' => $param['code']], '*', '', 'box_number');//获取箱唛店铺对应关系
        $msg = [];
        $pd = [];
        if (empty($receive)) {
            return returnArr(500, "头程签收明细不能为空");
        }
        if ($warehouseCountry['status'] == 20) {
            return returnArr(500, "已经确定入库不能操作");
        }
        if(empty($poDetail)){
            return returnArr(500, "采购单为空");
        }
        $detail=[];
        //sku对应多个箱唛号 要累加数量
        foreach ($receive as $v2) {
            $k2=$v2['code'].$v2['shop_id'].$v2['sku'];
            $detail[$k2]['code']=$v2['code'];
            $detail[$k2]['shop_id']=$v2['shop_id'];
            $detail[$k2]['sku']=$v2['sku'];
            $detail[$k2]['case_number'][]=$v2['case_number'];
            if(empty($detail[$k2]['quantity'])){
                $detail[$k2]['quantity']=$v2['quantity'];
            }else{
                $detail[$k2]['quantity']+=$v2['quantity'];
            }
        }
        foreach ($detail as $v) {
            if (empty($planCost[$v['sku']])) {
                $msg[] = "sku:{$v['sku']}的头程费用sku不存在";
                continue;
            }
            if (empty($planCost[$v['sku']]['head'])||$planCost[$v['sku']]['head']==0) {
                $msg[] = "sku:{$v['sku']}的头程费用不存在";
                continue;
            }
            if (empty($planDetail[$v['sku']])) {
                $msg[] = "sku:{$v['sku']}的在发运明细中不存在";
                continue;
            }
            if (empty($poDetail[$v['sku']])) {
                $msg[] = "sku:{$v['sku']}的在采购明细中不存在";
                continue;
            }
            $tempPd = [];
            $tempPd['warehouse_country_id'] = $warehouseCountry['id'];
            //$tempPd['case_number'] = join(',',$v['case_number']);
            $tempPd['sku'] = $v['sku'];
            $tempPd['sku_name'] = $planDetail[$v['sku']]['sku_name'];
            $tempPd['quantity'] = $v['quantity'];
            $tempPd['shop_id'] = $v['shop_id'];
            $tempPd['price'] = bcadd($poDetail[$v['sku']]['unit_price'], $planCost[$v['sku']]['head'], 5);
            $pd[] = $tempPd;
        }
        if (!empty($msg)) {
            return returnArr(500, $msg);
        }
        ToolModel::dbInsertOrUpdate('warehouse_country_detail', $pd);
        returnArr(1);
    }

    static public function getList($param)
    {
        if (empty($param['down'])) {
            $titles = [];
        } else {
            $titles = [
                'receipt_warehouse_str' => '收货仓库',
                'code' => '入库批次号',
                'bs_code' => '业务单号',
                'sku_num' => 'sku',
                'retail_company_str' => '货主',
                'type_str' => '入库类型',
                'status_str' => '状态',
                'date' => '入库时间'
            ];
        }
        return WarehousecountryModel::getList($param, $titles, "\app\index\service\WarehousecountryService::getListHandle");
    }

    static public function getListHandle($data)
    {
        //$company = ConfigBase::getCompanyAll();
        $warehouse = ConfigBase::getWarehouseAll();
        $skuNum = WarehousecountryModel::getSKuNum(array_column($data, 'id'));
        foreach ($data as &$v) {
            //$v['retail_company_str'] = $company[$v['retail_company']];
            $v['receipt_warehouse_str'] = $warehouse[$v['receipt_warehouse_id']] ?? '';
            $v['ship_warehouse_str'] = $warehouse[$v['ship_warehouse_id']] ?? '';
            $v['sku_num'] = $skuNum[$v['id']] ?? 0;
            $v['status_str'] = self::$statusStr[$v['status']];
            $v['type_str'] = self::$typeStr[$v['type']];
        }
        return $data;
    }

    //国家仓成本列表
    static public function getCostList($param)
    {
        if (empty($param['down'])) {
            $titles = [];
        } else {
            $titles = [
                'receipt_warehouse_str' => '仓库名称',
                'code' => '入库批次号',
                'sku' => 'sku',
                'quantity' => '总入库数量',
                'surplus' => '批次结余',
                'price' => '批次单价',
                'date' => '入库时间'
            ];
        }
        return WarehousecountryModel::getCostList($param, $titles, "\app\index\service\WarehousecountryService::getCostListHandle");
    }

    static public function getCostListHandle($data)
    {
        $warehouse = ConfigBase::getWarehouseAll();
        foreach ($data as &$v) {
            $v['receipt_warehouse_str'] = $warehouse[$v['receipt_warehouse_id']] ?? '';
        }
        return $data;
    }

    static public function costDetail($param)
    {
        $data = ToolModel::select('warehouse_country_out_cost', ['warehouse_country_cost_id' => $param['id']]);
        return returnArr(1, '', $data);
    }

    //国家仓库存列表
    static public function getStockList($param)
    {
        if (empty($param['down'])) {
            $titles = [];
        } else {
            $titles = [
                'receipt_warehouse_str' => '仓库名称',
                'sku' => 'sku',
                'physical_stock' => '实物库存',
                'preemption_stock' => '预占库存',
                'available_stock' => '可用库存',
                'cost' => '库存成本',
                'wam' => '加权单价',
                'stock_age' => '库龄',
            ];
        }
        return WarehousecountryModel::getStockList($param, $titles, "\app\index\service\WarehousecountryService::getCostListHandle");
    }

    //国家仓预占列表
    static public function getAdvanceList($param)
    {
        if (empty($param['down'])) {
            $titles = [];
        } else {
            $titles = [
                'code' => '预占单号',
                'bs_code' => '业务单号',
                'sku' => 'SKU',
                'receipt_warehouse_str' => '仓库名称',
                'quantity' => '预占数量',
                'type_str' => '预占类型',
                'date' => '预占时间',
                'status_str' => '预占状态',
            ];
        }
        return WarehousecountryModel::getAdvanceList($param, $titles, "\app\index\service\WarehousecountryService::getAdvanceListHandle");
    }

    //国家仓出库列表
    static public function getOutList($param)
    {
        if (empty($param['down'])) {
            $titles = [];
        } else {
            $titles = [
                'ship_warehouse_str' => '出货仓库',
                'code' => '出库批次号',
                'bs_code' => '业务单号',
                'sku_num' => 'sku',
                'type_str' => '出库类型',
                'status_str' => '状态',
                'date' => '出库时间'
            ];
        }
        return WarehousecountryModel::getOutList($param, $titles, "\app\index\service\WarehousecountryService::getOutListHandle");
    }

    static public function getOutListHandle($data)
    {
        $warehouse = ConfigBase::getWarehouseAll();
        $skuNum = WarehousecountryModel::getSKuNumByOut(array_column($data, 'id'));
        foreach ($data as &$v) {
            $v['ship_warehouse_str'] = $warehouse[$v['ship_warehouse_id']] ?? '';
            $v['receipt_warehouse_str'] = $warehouse[$v['receipt_warehouse_id']] ?? '';
            $v['status_str'] = self::$outStatus[$v['status']];;
            $v['type_str'] = self::$outType[$v['type']];
            $v['sku_num'] = $skuNum[$v['id']] ?? 0;
        }
        return $data;
    }

    static public function getAdvanceListHandle($data)
    {
        $warehouse = ConfigBase::getWarehouseAll();
        foreach ($data as &$v) {
            $v['receipt_warehouse_str'] = $warehouse[$v['receipt_warehouse_id']] ?? '';
            $v['status_str'] = self::$advanceStatus[$v['status']];;
            $v['type_str'] = self::$advanceType[$v['type']];
        }
        return $data;
    }

    static public function uploadHandle($data, $param)
    {
        $update = [];
        $msg = [];
        $wc = ToolModel::findByAttributes('warehouse_country', ['id' => $param['id']]);
        if ($wc['status'] == 20) {
            return returnArr(500, "已经确定入库不能操作");
        }
        $detail = ToolModel::select('warehouse_country_detail', ['warehouse_country_id' => $param['id']], '*', '', 'sku');
        foreach ($data as $v) {
            if (empty($detail[$v[0]])) {
                $msg[] = "sku:{$v[0]}在明细中不存在";
            }
            if (!preg_match("/^[1-9][0-9]*$/", $v[1])) {
                $msg[] = "sku:{$v[0]}入库数量必须为正整数";
            }
            $update[] = ['warehouse_country_id' => $param['id'], 'sku' => $v[0], 'quantity' => $v[1]];
        }
        if (!empty($msg)) {
            return returnArr(500, $msg);
        }
        ToolModel::dbInsertOrUpdate('warehouse_country_detail', $update);
        $detail = ToolModel::select('warehouse_country_detail', ['warehouse_country_id' => $param['id']]);
        return returnArr(1, '', $detail);
    }

    //入库操作
    static public function warehouseCountryIn($param)
    {
        $param['lockFunction']='\app\index\service\WarehousecountryService::updateStatus';
        $param['lockTxt']='warehouse_country_lock';
        return ToolModel::lock($param);
    }

    /**
     *确定入库
     * 成功要生成入库成本和库存管理
     * @param $param
     * @return array
     * @author xiejunyu
     */
    static public function updateStatus($param)
    {
        $wc = ToolModel::findByAttributes('warehouse_country', ['id' => $param['id']]);
        if ($wc['status'] == 20) {
            return returnArr(500, "已经确定入库不能操作");
        }
        $msg = [];
        $update = [];
        $detail = ToolModel::select('warehouse_country_detail', ['warehouse_country_id' => $param['id']], '*', '', 'sku');
        if (empty($param['list'])) {
            $msg[] = "入库明细中不存在";
        }
        foreach ($param['list'] as $v) {
            if (empty($detail[$v['sku']])) {
                $msg[] = "sku:{$v['sku']}在入库明细中不存在";
            }
            if (!preg_match("/^[1-9][0-9]*$/", $v['quantity'])) {
                $msg[] = "sku:{$v['sku']}入库数量必须为正整数";
            }
            $update[] = ['warehouse_country_id' => $param['id'],
                //'shop_id' => $v['shop_id'],
                //'case_number' => $v['case_number'],
                'sku' => $v['sku'],
                'quantity' => $v['quantity']];
        }
        if (!empty($msg)) {
            return returnArr(500, $msg);
        }
        ToolModel::dbInsertOrUpdate('warehouse_country_detail', $update);
        $pd = ToolModel::select('warehouse_country_detail', ['warehouse_country_id' => $param['id'], 'quantity' => 0], 'id', '', 'sku');
        if (!empty($pd)) {
            return returnArr(500, "失败,SKU" . join(',', array_keys($pd)) . "入库数量为0");
        }
        $row = ToolModel::updateData(['id' => $param['id'], 'status' => 10], ['status' => 20, 'date' => TIME], 'warehouse_country');
        if ($row) {
            $poWhere = [];
            //业务单号是发运单时 采购单修改为已完成
            if (substr($wc['bs_code'], 0, 2) == 'FY') {
                $poWhere = ['bs_code' => $wc['bs_code'], 'status' => 10];
                $shipDetail = ToolModel::select('ship_plan_detail', ['code' => $wc['bs_code'], 'ybr_status' => 1]);
                //校验入库明细中是否有发运配送的sku
                foreach ($shipDetail as $v) {
                    if (empty($detail[$v['sku']])) {
                        $msg[] = "发运的sku{$v['sku']}在入库明细中不存在";
                    }
                }
                if (!empty($msg)) {
                    return returnArr(500, $msg);
                }
            } elseif (substr($wc['bs_code'], 0, 2) == 'CG') {
                $poWhere = ['code' => $wc['bs_code'], 'status' => 10];
            }
            if(!empty($poWhere)){
                $poRow = ToolModel::updateData($poWhere, ['status' => 20], 'purchase_order');
                if (empty($poRow)) {
                    return returnArr(500, "修改采购单状态失败");
                }
            }
            //生成入库成本
            $detail = ToolModel::select('warehouse_country_detail', ['warehouse_country_id' => $param['id']]);
            $list = [];
            $stockList = [];
            $date = date('Y-m-d H:i:s');
            foreach ($detail as $v) {
                $temp = [];
                $temp['sku'] = $v['sku'];
                $temp['sku_name'] = $v['sku_name'];
                $temp['ctime'] = TIME;
                $temp['date'] = TIME;
                $temp['receipt_warehouse_id'] = $wc['receipt_warehouse_id'];
                $temp['code'] = $wc['code'];
                if (empty($list[$v['sku']])) {
                    $temp['quantity'] = $v['quantity'];
                } else {
                    $temp['quantity'] = $list[$v['sku']]['quantity'] + $v['quantity'];
                }
                $temp['surplus'] = $temp['quantity'];
                $temp['sku'] = $v['sku'];
                $temp['price'] = $v['price'];
                $list[$v['sku']] = $temp;
            }
            $id = ToolModel::insertData(array_values($list), 'warehouse_country_cost');
            if (empty($id)) {
                return returnArr(500, '生成入库成本错误');
            }
            //生成库存
            foreach ($list as $v2) {
                $stockList[] = "({$wc['receipt_warehouse_id']},'{$v2['sku']}','{$v2['sku_name']}',{$v2['quantity']},0,{$v2['quantity']}," . bcmul($v2['price'], $v2['quantity'], 5) . ",{$v2['price']},0,'{$date}')";
            }
            $sql = "INSERT INTO  warehouse_country_stock (receipt_warehouse_id,sku,sku_name,physical_stock,preemption_stock,available_stock,cost,wam,stock_age,ctime)
VALUES " . join(',', $stockList) . " ON DUPLICATE KEY UPDATE  physical_stock=physical_stock+VALUES(physical_stock),available_stock=available_stock+VALUES(physical_stock),cost=cost+VALUES(cost)";
            $row = ToolModel::execute($sql);
            foreach ($list as $v3) {
                //修改加权单价
                ToolModel::updateData(['receipt_warehouse_id'=>$wc['receipt_warehouse_id'],'sku'=>$v3['sku']],['wam'=>ToolModel::raw("cost/physical_stock")],'warehouse_country_stock');
                //修改库龄
                WarehousecountryModel::updateSkuStockAge(["receipt_warehouse_id"=>$wc['receipt_warehouse_id'],"sku"=>$v3['sku']]);
            }
            if (empty($row)) {
                return returnArr(500, '修改库存失败');
            }
            return returnArr(1, '入库成功',['url'=>'/#/Warehousecountry/input']);
        } else {
            return returnArr(1, '入库失败');
        }
    }

    /**
     *创建配送计划成功后生成国家仓预占单
     * @param $param
     * @return array
     * @author xiejunyu
     */
    static public function createAdvance($param)
    {
        $plan = ToolModel::findByAttributes("distribution_plan", ['id' => $param['id']]);
        $planPd = ToolModel::select("distribution_plan_detail", ['distribution_plan_id' => $param['id']]);
        foreach ($planPd as $v) {
            $data = [];
            $data['receipt_warehouse_id'] = $plan['warehouse_id_out'];
            $data['date'] = TIME;
            $data['sku'] = $v['sku'];
            $data['quantity'] = intval($v['quantity']);
            $data['bs_code'] = $plan['code'];
            $data['type'] = $param['type'];//调拨
            $data['status'] = 10;//10未释放
            $data['ctime'] = TIME;
            $sku = ToolModel::findByAttributes("warehouse_country_stock", ['sku' => $data['sku'], 'receipt_warehouse_id' => $data['receipt_warehouse_id']]);
            if (empty($sku)) {
                return returnArr(500, "sku:{$data['sku']}国家仓库存中不存在");
            }
            $advance = ToolModel::findByAttributes("warehouse_country_advance", ['sku' => $data['sku'], 'bs_code' => $data['bs_code']], 'id,status,quantity');
            if (empty($advance)) {
                 //可用库存
                if ($data['quantity'] > $sku['available_stock']) {
                    return returnArr(500, "sku:{$data['sku']}配送数量{$data['quantity']}大于国家仓库可用库存{$sku['available_stock']}");
                }
                $id = ToolModel::insertData($data, 'warehouse_country_advance');
                ToolModel::updateData(['id' => $id], ['code' => 'YZ' . $id], 'warehouse_country_advance');
                $num = $data['quantity'];
            } else {
                if ($advance['status'] == 20) {
                    return returnArr(500, '已被释放不允许修改');
                }
                //可用库存
                if ($data['quantity'] >$advance['quantity']&& (($data['quantity'] -$advance['quantity'])>$sku['available_stock'])) {
                    return returnArr(500, "sku:{$data['sku']}配送数量{$data['quantity']}大于国家仓库可用库存{$sku['available_stock']}");
                }
                unset($data['ctime']);
                $id = $advance['id'];
                ToolModel::updateData(['id' => $id], $data, 'warehouse_country_advance');
                $num = $data['quantity'] - $advance['quantity'];//10 20
            }
            if (!$id) {
                return returnArr(500, '生成预占错误');
            }
            if (empty($num) || $num == 0) {
                continue;
            }
            //减可用库存  加预占

            $sql="UPDATE `warehouse_country_stock`  SET `preemption_stock`=preemption_stock+{$num},`available_stock`=available_stock-{$num}
            WHERE  `sku` = '{$data['sku']}'  AND `receipt_warehouse_id` = {$data['receipt_warehouse_id']}  AND `utime` = '{$sku['utime']}'  AND `preemption_stock` = {$sku['preemption_stock']}  AND `available_stock` = {$sku['available_stock']}";
            $row=ToolModel::execute($sql);
/*            $row = ToolModel::updateData(['sku' => $data['sku'], 'receipt_warehouse_id' => $data['receipt_warehouse_id'], 'utime' => $sku['utime'], 'preemption_stock' => $sku['preemption_stock'], 'available_stock' => $sku['available_stock']],
                [
                    'preemption_stock' => ToolModel::raw("preemption_stock+{$num}"),//加预占库存
                    'available_stock' => ToolModel::raw("available_stock-{$num}")//减可用库存
                ]
                , 'warehouse_country_stock');*/
            if (!$row) {
                return returnArr(500, '减可用库存  加预占失败');
            }
        }
        return returnArr(1);
    }

    /**
     *配送计划审核失败释放预占库存
     * @param $param
     * @return array
     * @author xiejunyu
     */
    static public function cancelAdvance($param)
    {
        $plan = ToolModel::findByAttributes("distribution_plan", ['id' => $param['id']]);
        $planPd = ToolModel::select("warehouse_country_advance", ['bs_code' => $plan['code']]);
        if (empty($planPd)) {
            return returnArr(1);
        }
        foreach ($planPd as $v) {
            $row = ToolModel::updateData(['id' => $v['id']], ['status' => 20], 'warehouse_country_advance');
            if (!$row) {
                return returnArr(500, '更改预占释放状态失败!');
            }
            //减可用库存  加预占
            $row = ToolModel::updateData(['sku' => $v['sku'], 'receipt_warehouse_id' => $v['receipt_warehouse_id']],
                [
                    'preemption_stock' => ToolModel::raw("preemption_stock-{$v['quantity']}"),//减预占库存
                    'available_stock' => ToolModel::raw("available_stock+{$v['quantity']}")//加可用库存
                ]
                , 'warehouse_country_stock');
            if (!$row) {
                return returnArr(500, '加可用库存  减预占失败');
            }
        }
        return returnArr(1);
    }

    /**
     *出库成功释放预占库存 并减库存 算库存成本
     * @param $code
     * @return array
     * @author xiejunyu
     */
    static public function cancelAdvanceCost($code)
    {
        $planPd = ToolModel::select("warehouse_country_advance", ['bs_code' => $code]);
        foreach ($planPd as $v) {
            $row = ToolModel::updateData(['id' => $v['id']], ['status' => 20], 'warehouse_country_advance');
            if (!$row) {
                return returnArr(500, '更改预占释放状态失败!');
            }
            //减可用库存  加预占
            $row = ToolModel::updateData(['sku' => $v['sku'], 'receipt_warehouse_id' => $v['receipt_warehouse_id']],
                [
                    'preemption_stock' => ToolModel::raw("preemption_stock-{$v['quantity']}"),//减预占库存
                    'physical_stock' => ToolModel::raw("physical_stock-{$v['quantity']}")//减实物库存
                ]
                , 'warehouse_country_stock');
            if (!$row) {
                return returnArr(500, '减可用库存  减预占失败');
            }
            //修改库存成本
            $ret = WarehousecountryModel::getCostSum($v);
            //修改库龄
            WarehousecountryModel::updateSkuStockAge($v);
            if ($ret['code'] != 1) {
                return $ret;
            }
        }
        return returnArr(1);
    }

    /**
     * 前提是国家仓到店仓
     *生成出库单 按入库先进先出的规则
     * 如果采销类型  只需要传配送单号id
     * 如果调拨类型  需要传调拨单号allocate_order_sn和配送单号id
     * @param $param
     * @return array
     * @author xiejunyu
     */
    static public function createDoByDp($param)
    {
        $plan = ToolModel::findByAttributes("distribution_plan", ['id' => $param['id']]);
        $bsCode = empty($param['allocate_order_sn']) ? $plan['code'] : $param['allocate_order_sn'];
        $warehouse_country_out = ToolModel::findByAttributes("warehouse_country_out", ['bs_code' => $bsCode]);
        $advanceDetail = ToolModel::select("warehouse_country_advance", ['bs_code' => $plan['code']], '*', '', 'sku');

        if (!empty($warehouse_country_out)) {
            return returnArr(500, '出库单存在业务单号' . $bsCode);
        }
        if (empty($advanceDetail)) {
            return returnArr(500, '出库失败预占不存在');
        }
        $planPd = ToolModel::select("distribution_plan_detail", ['distribution_plan_id' => $param['id']]);
        $temp = [];
        $temp['receipt_warehouse_id'] = $plan['warehouse_id_rec'];
        $temp['ship_warehouse_id'] = $plan['warehouse_id_out'];//发货仓库
        $temp['bs_code'] = $bsCode;
        $temp['status'] = 20;
        $temp['type'] = $param['type'];
        $temp['user'] = CN_NAME;
        $temp['date'] = TIME;
        $temp['ctime'] = TIME;
        $id = ToolModel::insertData($temp, 'warehouse_country_out');
        $ck = 'CK' . $id;
        ToolModel::updateData(['id' => $id], ['code' => $ck], 'warehouse_country_out');
        $list = [];
        if (count($planPd) != count($advanceDetail)) {
            return returnArr(500, "配送计划sku数量和预占的sku数量不一致");
        }
        foreach ($planPd as $v) {
            $temp = [];
            $temp['sku'] = $v['sku'];
            $temp['sku_name'] = $v['sku_name'];
            $temp['quantity'] = $v['quantity'];
            $temp['demand_quantity'] = $v['quantity'];
            $temp['warehouse_country_out_id'] = $id;
            if (empty($advanceDetail[$v['sku']])) {
                return returnArr(500, "配送计划sku{$v['sku']}在预占库存中不存在");
            }
            if ($advanceDetail[$v['sku']]['quantity'] != $temp['quantity']) {
                return returnArr(500, "配送计划sku{$v['sku']}数量和预占库存中的数量不一致");
            }
            $temp1 = $temp;
            $temp1['warehouse_id_out'] = $plan['warehouse_id_out'];
            $temp1['bs_code'] = $bsCode;
            $temp1['code'] = $ck;
            //先进先出减库存
            $ret = self::getRecentlyCost($temp1);
            if ($ret['code'] != 1) {
                return $ret;
            }
            $temp['price'] = $ret['data'];
            $list[] = $temp;
        }
        ToolModel::insertData($list, 'warehouse_country_out_detail');
        $advanceRet = self::cancelAdvanceCost($plan['code']);//释放预占库存 并减库存 重新库存成本
        if ($advanceRet['code'] != 1) {
            return $advanceRet;
        }
        return returnArr(1, '', $id);
    }

    //根据先进先出的规则来获取最近入库的列表  并减批次结余
    static public function getRecentlyCost($temp)
    {
        $surplus = $temp['quantity'];
        $money = 0;
        $all = 0;
        do {
            $data = ToolModel::findByAttributes('warehouse_country_cost', ['sku' => $temp['sku'],
                'receipt_warehouse_id' => $temp['warehouse_id_out'], 'status' => 1, 'surplus' => ['>', 0]], '*', 'date asc');
            if (!empty($data)) {
                $row = 0;
                $ck = 0;
                if ($surplus >= $data['surplus']) {
                    $surplus = $surplus - $data['surplus'];
                    $ck = $data['surplus'];
                    $row = ToolModel::updateData(['id' => $data['id'], 'utime' => $data['utime'], 'surplus' => $data['surplus']], ['surplus' => 0, 'status' => 2], 'warehouse_country_cost');
                } elseif ($surplus < $data['surplus']) {
                    $ck = $surplus;
                    $row = ToolModel::updateData(['id' => $data['id'], 'utime' => $data['utime'], 'surplus' => $data['surplus']], ['surplus' => $data['surplus'] - $surplus], 'warehouse_country_cost');
                    $surplus = 0;
                }
                if (!$row) {
                    return returnArr(500, '修改库存失败!');
                }
                //记录每次出库明细对应的成本明细 先进先出
                ToolModel::insertData([
                    'warehouse_country_cost_id' => $data['id']
                    , 'code' => $temp['code']
                    , 'bs_code' => $temp['bs_code']
                    , 'sku' => $temp['sku']
                    , 'quantity' => $ck
                    , 'price' => $data['price']
                    , 'date' => TIME
                ], 'warehouse_country_out_cost');
                $all = $all + $ck;
                $money = bcadd($money, bcmul($data['price'], $ck, 5), 5);
            } else {
                return returnArr(500, '无可用库存出库!');
            }
        } while ($surplus > 0);
        if ($all != $temp['quantity']) {
            return returnArr(500, "失败,sku:{$temp['sku']}库存数量不足出库数量{$temp['quantity']}");
        }
        return returnArr(1, '', bcdiv($money, $all, 5));
    }
}